#ifndef CANBUSIOTHREAD_H
#define CANBUSIOTHREAD_H

#include <QObject>
#include <QThread>
#include <QTimer>
#include <QVector>
#include "ControlCAN.h"

typedef QVector<QString> StringVector;

class CanBusIoThread :public QThread
{
    Q_OBJECT
public:

    CanBusIoThread();

    uint mDeviceIndex;
    uint mDeviceType;

    uint mBaudRate;
    uint mCanChanIndex;

    uint externFlg = 0;

    QTimer *timer_;

    bool canOpen;

    void ClearBuf();

    bool isOpen();

    //打开设备
    bool OpenCAN(uint deviceType, uint deviceIndex, uint deviceCom,uint baudrate);

    //关闭设置
    bool CloseCAN();

    //初始化CAN
    bool InitCAN();

    bool sendCanData(int txNowId , QByteArray cmdBytes,bool bShow = true);

    bool canSetFrameFreq(uint frameFreq,uint txNowId);

    bool canOutputSwitch(bool isSwitchOn,uint txNowId);

    bool canOuputFrameFormat(uint format,uint txNowId);

    uint32_t Frame_CalCrc32(QByteArray data, uint32_t size);


    bool canSaveConfig(uint txNowId);

    bool canSystemReset(uint txNowId);

    bool canFactoryReset(uint txNowId);

    bool canBaudrate(uint baudrate,uint txNowId);

    bool canSetTxID(uint txID,uint txNowId);

    bool canSetRxID(uint txID,uint txNowId);

    //0x00 标准 0x01扩展
    bool canSetFrameType(uint frameType,uint txNowId);

    bool canSetParam(uint frameType,uint baudrate,ulong rxID,ulong txID,uint txNowId );

    QString canGetVersion(bool &result,uint txNowId);

    bool canFirmwareUpgrade(uint txID,QString binPath);

    bool canMiniFirmwareUpgrade(uint txID,uint8_t frameHead, QString binPath);

    //设置或者测试某一项
     bool canTestOneItem(uint canTxId, QString SendCmdStr, int needAck, QString GoodAckStr);
     bool canTestOneItem_Mini_TxRxID(uint canTxId, QString SendCmdStr, int needAck, QString GoodAckStr, uint txID, uint rxID);
     bool canTestOneItem_TF03_TxID(uint canTxId, QString SendCmdStr, int needAck, QString GoodAckStr, uint txID);
     bool canTestOneItem_TF03_RxID(uint canTxId, QString SendCmdStr, int needAck, QString GoodAckStr, uint RxID);

     bool stopped;

     QVector<uint16_t> passDist_;

     QList<int> passFacDist_;

     QVector<uint16_t> passAmp_;
     QVector<QString> passRxFrame_;

    int numFrame_;
    int freq_;


    unsigned char calc_checksum(QByteArray &cmd);
   // bool read_ack(QByteArray ack);
    bool read_ack(QByteArray ack, QByteArray &targetFrame, uint checkcnt = 100, bool isShow = true);

    bool send_can_upgradecmd(uint canId, unsigned short index, QByteArray data, unsigned short frame_cnt);
    bool send_can_upgradeheadcmd(uint canId, uint binFileLength);



    bool minican_reset(uint canId,uint8_t frameHead);
    bool minican_enterbl(uint canId,uint8_t frameHead);
    bool minican_enterbl_bridge(uint canId, uint8_t frameHead);

    bool minican_erase_flash(uint canId, uint binLength,uint32_t binCrc32, uint packsize,uint8_t frameHead);
    bool minican_binupgrade(uint canId, QByteArray binBytes,uint packsize, unsigned short pack_id,uint8_t frameHead);
    bool minican_switch2device(uint canId,uint8_t frameHead);

    bool minican_checkrcv(uint8_t frameHead, int tryCnt = 100);


    bool sendTestCanData(int ID, QByteArray cmdBytes);

    bool Check_Test_Ack(QByteArray GoodAck,uint checkcnt);



    bool stopRun();
    bool startRun();


signals:
   void signalFacDistance(QList<int> _dist,uint RidarId);
   void signalDistance(QVector<uint16_t> _dist, QVector<uint16_t> _amp, const StringVector& _hexStrArr,int _freq);
   void signalSerialCmdSend(QByteArray cmd);
   void signalDataRcv(QByteArray cmdRx);
   void signalCANUpdateProcessbar(float);
   void signalCANUpgradeResult(bool);
   bool Signal_canMiniFirmwareUpgrade(uint txID, uint8_t frameHead, QString binPath);

public:

    void run() ;
    void sleep(unsigned int msec);

    void CAN_ClearBuffer();
    void msleep(unsigned int msec);


    bool Check_Test_Ack(uint checkcnt);
    bool sendCanDataAndTryReceive(int ID, QByteArray cmdBytes);

    //Try and test factory
    bool CanTryFactoryReset(uint txId);


private slots:
       void slotCalcFreq();


   bool Slot_canMiniFirmwareUpgrade(uint txID, uint8_t frameHead, QString binPath);
};

#endif // CANBUSIOTHREAD_H
